feat(book): documentation navigation spine + derived membership (ADR-0046 §6, P3a/P3b)#1879
Merged
Conversation
…ved membership
Adds §6 to ADR-0046 specifying the P3 navigation model. A `book` is a metadata
element that stores only an ordered spine (groups); membership is derived by
rule (`include` glob/tag) plus optional per-doc `order`/`group`, never a central
array. This is chosen so AI authoring stays create-and-forget (no central-array
read-modify-write, §6.2.1) and runtime overlay stays merge-safe under RFC 7396.
Also specified: the implicit per-package book (packageId), `audience` access
(org / public≡guest / {profile}) enforced at the read layer, and a host-based
anonymous "library" portal reusing apps/docs (Fumadocs + per-host ISR) rather
than greenfield SSR. No `meta.json`: `book` is metadata, authored as *.book.ts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…p resolver (ADR-0046 §6, P3a) - BookSchema (spine: ordered groups + audience + identity), BookGroupSchema, BookNodeSchema, defineBook(); additive scalar `doc.order` / `doc.group`. - resolveBookTree(): pure derived-membership resolver — the AI-safety core. A doc joins a group by `include` glob/tag or explicit `doc.group`; explicit `pages` override (verbatim order, `---`, `...` rest, missing-doc, object nodes); unmatched docs → synthetic Uncategorized; first-group-wins dedup; package-scoped includes. - deriveImplicitPackageBook(): the implicit per-package book (no "flat" fork). - Register `book` metadata type (allowOrgOverride:true, loadOrder 99); artifact field `books` → `book`; `stack.books`. - 15 resolver/schema tests; spec tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iring (ADR-0046 §6, P3b) - REST `GET /meta/book/:name/tree` resolves a book spine against the docs that exist now into a rendered tree (resolveBookTree); unknown name → implicit per-package book. Read-layer `audience` gating: anonymous callers get a book only when its audience is `public` (else 401), enforced in the read path — not just the UI — since /meta reads are anonymous-reachable. - Register `book` across the runtime metadata enumerations that were missing it: PLURAL_TO_SINGULAR (`books`→`book`), engine.registerApp metadataArrayKeys, app-plugin app-category keys, and the builtin type-schema map (book→BookSchema for Studio editing / diagnostics). Export `defineBook` from the spec root. - Showcase ships a real `showcase_manual` book (audience: public) demonstrating explicit `pages` + `...` rest (start) and a derived `include` rule (guides). Verified live (artifact boot): GET /meta/book → 1 item; /tree returns the derived tree (guides filled by rule, other-package docs → Uncategorized); public book serves anonymously (200), implicit org book is gated (401). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the
booknavigation element specified in ADR-0046 §6 (merged in #1865).Core idea — a spine, not a container
A
bookstores only an ordered spine (groups +audience+ identity). Membership is derived from a rule on each group (includeglob/tag) plus an optional scalardoc.order/doc.group— never a centralpagesarray. This is the load-bearing choice (ADR §6.2.1):ordermerges cleanly.What's here
P3a — spec + resolver (
@objectstack/spec)BookSchema(spine),BookGroupSchema,BookNodeSchema,defineBook(); additivedoc.order/doc.group.resolveBookTree()— pure resolver:includeglob/tag + explicitdoc.group; explicitpagesoverride (verbatim order,---,...rest, missing-doc, object nodes); unmatched docs → synthetic Uncategorized; first-group-wins dedup; package-scoped includes.deriveImplicitPackageBook()for the implicit per-package book.book(render-time type,allowOrgOverride: true,loadOrder: 99);book → BookSchemain the type-schema map;stack.books; artifact fieldbooks → book.tscclean.P3b — runtime + REST (
@objectstack/objectql,@objectstack/rest,@objectstack/runtime)book/booksthrough the runtime type enumerations (PLURAL_TO_SINGULAR, engineregisterApp, app-plugin category keys).GET /meta/book/:name/treeresolves the tree; read-layeraudiencegating (anonymous gets a book only whenaudience: 'public', else 401 — enforced in the read path, not just the UI).showcase_manualbook (audiencepublic).Verified live (artifact boot)
Known follow-up
os dev) serving path does not yet surfacebookitems (artifact-bootos startdoes). The book registers into the boot engine but the env-scoped serving protocol reads a separate store whose enumeration still needs the type wired; tracked for a follow-up.apps/docsISR render live in theobjectui/apps-docssurfaces (cross-repo); this PR delivers the backend the portal consumes.🤖 Generated with Claude Code